//----------------------------------------------------------- // Purpose: Postfix calculator with variables. // Author: John Gauch //----------------------------------------------------------- #include #include #include #include "list/list.h" #include "stack/stack.h" using namespace std; //----------------------------------------------------------- // Function that extracts space separated tokens from input. // Returns true when token is found, and false when not found. //----------------------------------------------------------- bool get_token(string & input, string & token) { // Find start of token unsigned int start = 0; while ((start < input.length()) && (input.at(start) == ' ')) start++; // Find end of token unsigned int end = start; while ((end < input.length()) && (input.at(end) != ' ')) end++; // Extract token from input token = input.substr(start, end - start); input = input.substr(end, input.length() - end); return (token.length() > 0); } //----------------------------------------------------------- // Parse postfix expression and return value. //----------------------------------------------------------- int parse_postfix(string & input, List & list) { // Parse expression to get value Stack stack; int num1, num2, result; string token; while (get_token(input, token)) { // Push integers on stack if ((token[0] >= '0') && (token[0] <= '9')) stack.Push(stoi(token)); // Push variables on stack else if (((token[0] >= 'a') && (token[0] <= 'z')) || ((token[0] >= 'A') && (token[0] <= 'Z'))) { list.Search(token, result); stack.Push(result); } // Handle addition else if (token[0] == '+') { if (stack.GetLength() < 2) { cout << "Error: Not enough data for '" << token << "' operation\n"; return 0; } stack.Pop(num2); stack.Pop(num1); stack.Push(num1 + num2); } // Handle subtraction else if (token[0] == '-') { if (stack.GetLength() < 2) { cout << "Error: Not enough data for '" << token << "' operation\n"; return 0; } stack.Pop(num2); stack.Pop(num1); stack.Push(num1 - num2); } // Handle multiplication else if (token[0] == '*') { if (stack.GetLength() < 2) { cout << "Error: Not enough data for '" << token << "' operation\n"; return 0; } stack.Pop(num2); stack.Pop(num1); stack.Push(num1 * num2); } // Handle division else if (token[0] == '/') { if (stack.GetLength() < 2) { cout << "Error: Not enough data for '" << token << "' operation\n"; return 0; } stack.Pop(num2); stack.Pop(num1); stack.Push(num1 / num2); } } // Error checking on stack if (stack.GetLength() < 1) { cout << "Error: Not enough data for expression\n"; return 0; } else if (stack.GetLength() > 1) { cout << "Error: Too much data for expression\n"; return 0; } // Print result stack.Pop(result); return result; } //----------------------------------------------------------- // Main program for testing. //----------------------------------------------------------- int main() { // Process postfix expressions List list; while (true) { // Get user input string variable, equals, input; cout << "Enter postfix expression: "; cin >> variable; // Terminate program if (variable == ".") return 0; // Print variable values else if (variable == "?") { cout << "Variables: \n"; list.Print(); } // Parse postfix expression else { cin >> equals; getline(cin, input); int result = parse_postfix(input, list); cout << variable << " = " << result << endl; list.Insert(variable, result); } } }